import { createPinia } from 'pinia'
import { createApp } from 'vue'
import App from './App.vue'
import './styles/base.css'
import './styles/index.css'
const pinia = createPinia()

createApp(App).use(pinia).mount('#app')

/* 
1. 如果不希望有其他的插件提示，可以禁用掉 例如 uni-app，小程序的插件
2. 希望有自动引进(官方有一些小bug，可能是required，那么就需要手动 import 引进)
    2.1 volar 自带
    2.2 Auto Import
*/

/* 
vue3基本语法小结
vue2 和 vue3 的区别(面试高频题目)
    1. 数据响应式原理重新实现 (ES6 proxy 替代了 ES5 的 Object.defineProperty)
    2. 提供了 composition api, 可以更好的逻辑复用与代码组织
    3. 源码用 typescript 重写, 有更好的类型推导 (类型检测更为严格, 更稳定)
    4. 虚拟 DOM - 新算法 (更快 更小)
    5. 模板可以有多个根元素

1. vite 的构建工具 - 与webpack的区别
vite使用的是原生的 esm 包，不需要编译，它是先起服务，需要用到模块再去加载，所以速度非常快
webpack：需要先把文件编译(es5的浏览器也能识别),编译完成后再起服务，速度较慢

2. 怎么创建vue3的项目
    0. node>=16
    1. npm create vite@latest
    2. npm i 

3. vue3插件介绍
    1. vscode - 安装 volar(兼容vue2，可以值使用volar，把 vuter、vuter 卸载)
    2. 谷歌浏览器 - Vue.js devtools(安装完重启浏览器即可)，保证版本在 6.1以上即可(兼容vue2)

语法：
1. setup 生命周期钩子函数 - 实际工作中，请直接使用 setup 语法糖
    1. 组件中 compositionAPI 的起点，业务代码都放里面
    2. setup 会在 beforeCreate 钩子函数之前执行
    3. setup 中不能使用 this, this 指向 undefined
    4. 模版中需要使用的数据和函数，需要在 `setup` 返回
    需要在 script 加上  setup 的属性，开启语法糖
        1. export default 不用自己写
        2. setup() 不需要自己写
        3. return 的数据，不需要自己写

2. reactive - 把传入的 复杂类型的数据，转换成响应式
    把传入的对象，包裹一层 proxy 盒子返回，从而实现响应式
3. ✨ref - 把传入的任意类型，转换成响应式对象,里面有唯一的属性 value 取值

4. computed 计算属性
    语法：computed( ()=>{ // 依赖数据改变时，会自动触发回调函数} )

5. watch 侦听器
    语法： watch(数据源,()=>{},{deep:true})

6. 生命周期
    创建前后没有，直接使用 setup 即可
    beforeMount --- onBeforeMount
    ✨✨✨mounted --- onMounted
    beforeUpdate --- onBeforeUpdate
    updated --- onUpdated
    beforeDestory --- onBeforeUnmount
    ✨✨✨destoryed --- onUnmounted

7. 父子通信
    父传子
        1. 父传子: <Son :money="money" :car="car"></Son>
        2. 子组件接受： defineProps(['属性名1','属性名2'...])
    子传父
        1. 子组件先定义好要触发的方法: const emit = defineEmits(['方法名1','方法名2'...])
        2. emit('方法名',payload)
        3. 父组件需要绑定好对应方法名 <Son @方法名="父组件的方法">

8. 依赖注入 - provide 和 inject
    作用：实现跨层级的数据（方法）传递
    注意：不能实现兄弟组件通信，所以一般工作中习惯用 pinia
    语法：和localSto非常相似
        1. 组件元素定义和提供
            const money = ref(10000)
            provide('属性名',money) //只需要传递money这个ref响应式对象即可
        2. 后代元素获取
            const money = inject('属性名') //拿到ref响应式对象

9. 模板中 ref 属性的使用
    作用：获取 dom 或者 子组件
    1. 定义一个响应式对象 const domRef = ref(null)
    2. 在模板中(template)通过ref属性绑定，<Son ref="domRef">
    3. 页面渲染完成，就能通过 domRef.value 拿到 dom 或者 子组件
    注意✨✨✨：如果要获取子组件上面的 属性/方法
    必须在子组件上面，自己暴露出去 ---  defineExpose({money,sayHi})
    父组件就能获取到子组件的属性和方法了
    domRef.value.money / domRef.value.sayHi()

10. vue3中废弃了 过滤器，使用函数替代即可
11. toRefs作用：使用 toRefs 可以保证该对象展开的每个属性都是响应式的
        const user = ref({ name: 'zs', age: 18 });
        const { name, age } = toRefs(user.value)

vue3 插件：
1. vue-router
实际工作中对应的版本：vue@3 + vue-router@4 + pinia(vuex5)
创建路由实例，不要背下来，需要用的时候，就复制！！！
1. 安装vue-router
2. 创建路由实例
3. main.js 引进路由实例，通过插件方式挂载到app上( createApp(App).use(router) )

2.vuex(可以用，但是工作中更倾向使用 pinia)

3.pinia:官方的全局状态管理
state 相当于组件中 data
getters 相当于组件中的 computed
actions 相当于组件中的 methods
✨✨✨ pinia 中没有 mutations，无论同步异步，都可以在 actions 完成

pinia创建步骤
1. main.js 通过 createPinia 创建了实例，通过插件挂载到 app
2. defineStore  定义pinia模块的数据,拿到返回的方法，导出去
    export const useTodosStore = defineStore('todos', { 模块的state,getters,actions})
3. 页面使用，值需要引进方法 useTodosStore 即可(一般都是用模块管理)

✨✨✨模块化
1. 每一个模块都划分到对应的文件里面，导出对应的方法，例如 store/modules/todos.js，store/modules/user.js
2. store/index.js 建立总主管，把所有的模块都统一引过来和导出去
    export * from './modules/counter'
    export * from './modules/user'
3. 页面使用，在 总主管 统一导入使用即可
    import { useCounterStore, useUserStore } from './store';
*/